﻿<?php

    function readn($socket, $nRead)
    {
        if ($socket == NULL || $nRead < 0)
        {
            return NULL;
        }

        $content = "";
        while (strlen($content) < $nRead)
        {
            $t = socket_read($socket, $nRead - strlen($content), PHP_BINARY_READ);
            if ($t == NULL)
            {
                return NULL;
            }
            $content .= $t;
        }
        return $content;
    }

    function WriteAudioFile($audio, $file)
    {
        if ($audio == NULL || strlen($audio) == 0)
        {
            printf("NULL audio file");
            return;
        }
        $file = fopen($file, "w");
        fwrite($file, $audio, strlen($audio));
        fclose($file);
    }

    function Text2MP3($req)
    {
        if (strlen($req) == 0)
        {
            return NULL;
        }
        
        $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        $SVR_IP = "bb-test-nlp20.vm.baidu.com";
        $SVR_PORT = 4040;
        if (!socket_connect($sock, $SVR_IP, $SVR_PORT))
        {
            printf("Failed to connect " . $SVR_IP . ":" . $SVR_PORT . "\n");
            return NULL;
        }
        
        $lenSent = socket_send($sock, $req, strlen($req), 0);
        printf("Wav file size: %u, Req size: %u, Sent size: %u\n",
            strlen($audio), strlen($req), $lenSent);
        
        $TEXT_TO_MP3_HEADER_LEN = 10;
        $response = readn($sock, $TEXT_TO_MP3_HEADER_LEN);
        if (strlen($response) != $TEXT_TO_MP3_HEADER_LEN)
        {
            printf("Failed to read wav2mp header\n");
            socket_close($sock);
            return NULL;
        }

        $id = (ord($response[0]) << 24) | (ord($response[1]) << 16) | (ord($response[2]) << 8) | ord($response[3]);
        if ($id != 0x0A0B0C0D)
        {
            printf("Invalid ID: %u\n", $id);
            socket_close($sock);
            return NULL;
        }
        $version = ord($response[4]) << 8 | ord($response[5]);
        $dataLen = ord($response[6]) << 24 | ord($response[7]) << 16 | ord($response[8]) << 8 | ord($response[9]);
        printf("id=%u, version=%u, dataLen=%u\n", $id, $version, $dataLen);
        
        $mp3 = readn($sock, $dataLen);
        if (strlen($mp3) != $dataLen)
        {
            printf("Failed to recv body. size: %u\n", $dataLen);
            socket_close($sock);
            return NULL;
        }
        return $mp3;
    }
    
    function MakeText2MP3Req($text, $textEncoding, $lan)
    {
        if (strlen($text) == 0 || strlen($textEncoding) == 0
            || (strtoupper($lan) != "ZH" && strtoupper($lan) != "EN"))
        {
            return NULL;
        }
        
        $text = $textEncoding != "GB2312"
            ? iconv($textEncoding, "GB2312", $text) : $text;
        
        printf("text = [%s]", $text);
        if (strlen($text) == 0)
        {
            printf("Failed to convert text from [%s] to [%s]\n", $textEncoding, "GB2312");
            return NULL;
        }
        
        $req = "";
        $req .= chr(0xA);
        $req .= chr(0xB);
        $req .= chr(0xC);
        $req .= chr(0xD);
        
        // version = 0
        $req .= chr(0x0);
        $req .= chr(0x0);
        
        $HEADER_LEN = 10;
        $dataLen = $HEADER_LEN + 4 + strlen($text);
        printf("DataLen = [%u]", $dataLen);

        $req .= chr(($dataLen >> 24) & 0x000000FF);
        $req .= chr(($dataLen >> 16) & 0x000000FF);
        $req .= chr(($dataLen >> 8) & 0x000000FF);
        $req .= chr(($dataLen) & 0x000000FF);
        
        $lanCode = strtoupper($lan) == "ZH" ? 0 : 1;
        $req .= chr(($lanCode >> 8) & 0x000000FF);
        $req .= chr(($lanCode) & 0x000000FF);
        
        // encoding: gb2312
        $req .= chr(0x00);
        $req .= chr(0x00);
        
        $req .= $text;
        
        return $req;
    }
    
    function Main()
    {
        // $text = "今天天气有些阴沉，空气质量不是很好，大家在办公室努力工作，也就顾不得那么多了。";
        $text = "Hello world, Baidu, google and micorsoft are great companies";
        $textEncoding = "UTF-8";

        $req = MakeText2MP3Req($text, $textEncoding, "EN");
        // $req = MakeText2MP3Req($text, $textEncoding, "ZH");
        $mp3 = Text2MP3($req);
        WriteAudioFile($mp3, "jtts.mp3");
        
        /// header("Content-Type: audio/wav");
        // header(sprintf("Content-Length: %u", strlen($audio)));
        // echo $audio;
    }

    Main();
?>
